﻿using Benchmark;
using BenchmarkDotNet.Running;
using Devonline.Core;
using Devonline.Logging;
using Devonline.MessageQueue;
using Devonline.MessageQueue.Pulsar;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);
builder.Host.AddLogging();
var services = builder.Services;
services.AddLogging();

var allType = "all";
var commandLine = new CommandLineArgumentParser(args);
var type = commandLine.GetValue<string>("-t") ?? commandLine.GetValue<string>("--type") ?? nameof(ImageBenchmark);
var benchmark = commandLine.Has("-b") || commandLine.GetValue<bool>("--benchmark");

Console.WriteLine($"the benchmark of {type} start now!");

if (type == allType || type == nameof(MessageQueue))
{
    services.AddMessageQueue(new PulsarEndpoint { Name = nameof(Benchmark), Host = "pulsar://api.pigeoncn.com:6650" }, ServiceLifetime.Singleton);
}

var app = builder.Build();
await app.StartAsync();

//var logger = app.Services.GetService<ILogger<Program>>();

if (benchmark)
{
    if (type == nameof(Fibonacci) || type == allType)
    {
        Console.WriteLine($"the benchmark of {nameof(Fibonacci)} start!");
        BenchmarkRunner.Run<Fibonacci>();
    }

    if (type == nameof(ImageBenchmark) || type == allType)
    {
        Console.WriteLine($"the benchmark of {nameof(ImageBenchmark)} start!");
        BenchmarkRunner.Run<ImageBenchmark>();
    }
}
else
{
    var count = commandLine.Has("-c") ? commandLine.GetValue<int>("--count") : AppSettings.UNIT_THOUSAND;
    var parallel = commandLine.Has("-pa") ? commandLine.GetValue<bool>("--parallel") : true;
    var parallelRate = commandLine.Has("-pr") ? commandLine.GetValue<int>("--parallelRate") : AppSettings.UNIT_TEN;
    var parallelCount = count * parallelRate;

    if (type == nameof(Fibonacci) || type == allType)
    {
        Console.WriteLine($"the benchmark of {nameof(Fibonacci)} start!");
        var fibonacci = new Fibonacci();
        fibonacci.LoopRun(count);
        if (parallel)
        {
            fibonacci.ParallelRun(parallelCount);
        }
    }

    if (type == nameof(MessageQueue) || type == allType)
    {
        var messageQueueService = app.Services.GetService<IMessageQueueService>()!;
        Console.WriteLine($"the benchmark of {nameof(MessageQueue)} publish!");
        var messageQueue = new MessageQueue(messageQueueService);
        await messageQueue.ParallelPublicAsync(parallelCount);
        await messageQueue.StopAsync();

        //Console.WriteLine($"the benchmark of {nameof(MessageQueue)} subscribe!");
        //var messageQueue = new MessageQueue(messageQueueService);
        //messageQueue.Start();
        //var total = 0;
        //await messageQueue.SubscribeAsync(async messages =>
        //{
        //    total = messages.Count;
        //    Console.WriteLine($"the benchmark of {nameof(MessageQueue)} receive {messages.Count} messages!");
        //    await messageQueue.StopAsync();
        //});

        //while (total < parallelCount)
        //{
        //    await Task.Delay(1000);
        //}

        //Console.WriteLine($"the benchmark of {nameof(MessageQueue)} receive {total} messages!");
    }

    if (type == nameof(ImageBenchmark) || type == allType)
    {
        Console.WriteLine($"the benchmark of {nameof(ImageBenchmark)} start!");
        var imageBenchmark = new ImageBenchmark();
        imageBenchmark.RunImageSharp();
        imageBenchmark.RunSkiaSharp();
        imageBenchmark.RunNetVips();
    }
}

Console.WriteLine($"the benchmark of {type} complete!");